<template>
  <div class="arcgis">
    <div id="info">{{ infomation }}</div>
    <div class="map" id="map" ref="map"></div>
  </div>
</template>
<script lang="ts">
import Vue from 'vue';
import Component from 'vue-class-component';

import 'ol/ol.css';
import EsriJSON from 'ol/format/EsriJSON';
import Map from 'ol/Map';
import VectorSource from 'ol/source/Vector';
import View from 'ol/View';
import XYZ from 'ol/source/XYZ';
import { Fill, Stroke, Style } from 'ol/style';
import { Tile as TileLayer, Vector as VectorLayer } from 'ol/layer';
import { createXYZ } from 'ol/tilegrid';
import { fromLonLat } from 'ol/proj';
import { tile as tileStrategy } from 'ol/loadingstrategy';
import jsonp from 'jsonp';
@Component({
  components: {},
})
export default class ArcGIS extends Vue {
  private serviceUrl: string = `https://sampleserver3.arcgisonline.com/ArcGIS/rest/services/Petroleum/KSFields/FeatureServer/`;
  private layer: any = '0';
  private esrijsonFormat: any = new EsriJSON();
  private styleCache: any = {
    ABANDONED: new Style({
      fill: new Fill({
        color: 'rgba(225, 225, 225, 255)',
      }),
      stroke: new Stroke({
        color: 'rgba(0, 0, 0, 255)',
        width: 0.4,
      }),
    }),
    GAS: new Style({
      fill: new Fill({
        color: 'rgba(255, 0, 0, 255)',
      }),
      stroke: new Stroke({
        color: 'rgba(110, 110, 110, 255)',
        width: 0.4,
      }),
    }),
    OIL: new Style({
      fill: new Fill({
        color: 'rgba(56, 168, 0, 255)',
      }),
      stroke: new Stroke({
        color: 'rgba(110, 110, 110, 255)',
        width: 0,
      }),
    }),
    OILGAS: new Style({
      fill: new Fill({
        color: 'rgba(168, 112, 0, 255)',
      }),
      stroke: new Stroke({
        color: 'rgba(110, 110, 110, 255)',
        width: 0.4,
      }),
    }),
  };
  private vectorSource = new VectorSource({
    loader: (extent: any, resolution: any, projection: any) => {
      let url =
        this.serviceUrl +
        this.layer +
        '/query/?f=json&' +
        'returnGeometry=true&spatialRel=esriSpatialRelIntersects&geometry=' +
        encodeURIComponent(
          '{"xmin":' +
            extent[0] +
            ',"ymin":' +
            extent[1] +
            ',"xmax":' +
            extent[2] +
            ',"ymax":' +
            extent[3] +
            ',"spatialReference":{"wkid":102100}}',
        ) +
        '&geometryType=esriGeometryEnvelope&inSR=102100&outFields=*' +
        '&outSR=102100';
      jsonp(url, (error: any,response:any) => {
        
        if (response.error !== undefined && response.error !== null) {
          console.error(response.error.message + '\n' + response.error.details.join('\n'));
        } else {
          // dataProjection will be read from document
          let features = this.esrijsonFormat.readFeatures(response, {
            featureProjection: projection,
          });
          if (features.length > 0) {
            this.vectorSource.addFeatures(features);
          }
        }
      });
    },
    strategy: tileStrategy(
      createXYZ({
        tileSize: 512,
      }),
    ),
  });
  private vector = new VectorLayer({
    source: this.vectorSource,
    style:  (feature: any) => {
      let classify = feature.get('activeprod');
      return this.styleCache[classify];
    },
  });
  private raster = new TileLayer({
    source: new XYZ({
      attributions:
        'Tiles © <a href="https://services.arcgisonline.com/ArcGIS/' +
        'rest/services/World_Topo_Map/MapServer">ArcGIS</a>',
      url:
        'https://server.arcgisonline.com/ArcGIS/rest/services/' +
        'World_Topo_Map/MapServer/tile/{z}/{y}/{x}',
    }),
  });
  private map: any;
  private infomation: any = '';
  public mounted() {
    this.createMap(() => {
      this.map.on('pointermove', (evt: any) => {
        if (evt.dragging) {
          return;
        }
        let pixel = this.map.getEventPixel(evt.originalEvent);
        this.displayFeatureInfo(pixel);
      });

      this.map.on('click', (evt: any) => {
        this.displayFeatureInfo(evt.pixel);
      });
    });
  }
  public createMap(cb: any) {
    this.map = new Map({
      layers: [this.raster, this.vector],
      target: this.$refs['map'],
      view: new View({
        center: [11438968.29747108, 2886802.8809009036],
        zoom: 4,
      }),
    });
    if (this.map) {
      cb && cb();
    }
  }

  public displayFeatureInfo(pixel: any) {
    let features: any = [];
    this.map.forEachFeatureAtPixel(pixel, (feature: any) => {
      features.push(feature);
    });
    if (features.length > 0) {
      let info = [];
      let i, ii;
      for (i = 0, ii = features.length; i < ii; ++i) {
        info.push(features[i].get('field_name'));
      }
      this.infomation = info.join(', ') || '(unknown)';
      this.map.getTarget().style.cursor = 'pointer';
    } else {
      this.infomation = '';
      this.map.getTarget().style.cursor = '';
    }
  }
}
</script>
<style lang="less" scoped>
.map {
  height: calc(100vh - 274px);
  width: 100%;
}
</style>